import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { CreateProductDto } from './dto/create-product.dto';
import { Product } from './product.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, Raw, In, Not } from 'typeorm';
import { cryptoString } from '../libs/lib';
import { RemoveProductDto } from './dto/remove-product.dto';

@Injectable()
export class ProductsService {
  constructor(
    @InjectRepository(Product)
    private productsRepository: Repository<Product>,
  ) {}

  // 增加
  async create(createProductDto: CreateProductDto): Promise<any> {
    const { createdAt } = createProductDto;
    createProductDto.createdAt = createdAt || new Date();
    createProductDto.updatedAt = new Date();

    delete createProductDto.id;

    return await this.productsRepository.save(createProductDto);
  }

  // 删除
  async delete(removeProductDto: RemoveProductDto): Promise<any> {
    const { ids } = removeProductDto;

    return this.productsRepository.delete(ids);
  }

  // 更新
  async update(updateProductData): Promise<any> {
    const { id, updateProductDto } = updateProductData;
    updateProductDto.updatedAt = new Date();

    return await this.productsRepository.update(id, updateProductDto);
  }

  // 列表
  // async findAll(query: any): Promise<any> {
  //   const { keyword, category, page = 1, limit = 10, recommend } = query;
  //   const skip = (page - 1) * limit;

  //   let params = {
  //     skip,
  //     take: limit,
  //   };
  //   const selectFields = ['id', 'name', 'pic', 'addr', 'category']; // 需要的字段
  //   let whereParams = {};

  //   if (keyword) {
  //     whereParams = Object.assign(whereParams, {
  //       name: Like(`%${keyword}%`),
  //     });
  //   }

  //   if (category) {
  //     whereParams = Object.assign(whereParams, {
  //       category,
  //     });
  //   }

  //   if (recommend) {
  //     whereParams = Object.assign(whereParams, {
  //       recommend: recommend === 'true' ? true : '',
  //     });
  //   }

  //   params = Object.assign(
  //     params,
  //     {
  //       select: selectFields, // Add your fields here
  //       where: whereParams,
  //     },
  //     {
  //       order: {
  //         updatedAt: 'DESC',
  //       },
  //     },
  //   );

  //   const [data, total] = await this.productsRepository.findAndCount(params);

  //   return {
  //     total,
  //     data,
  //   };
  // }

  // gpt优化查询
  // 在 TypeORM 中，使用 createQueryBuilder 可以创建更复杂的查询，比如可以进行联表查询。在这种情况下，我们需要一种方式来区分不同的表和字段。别名就是这样一种方式。
  // 当你调用 createQueryBuilder('product') 时，你为当前的实体（也就是 productsRepository 指向的实体）指定了一个别名 'product'。然后，在后续的查询中，你可以使用这个别名来引用这个实体的字段，比如 'product.name'、'product.category' 等等。
  // 尽管在这个具体的例子中，我们可能并没有进行联表查询，但别名依然是必须的。这是因为 TypeORM 的设计使得即使在单表查询中也需要使用别名，这样可以统一 API，并允许你随时增加更复杂的查询而无需大量更改代码。
  // 这就是为什么我们需要为 createQueryBuilder 指定别名的原因。即使它只从 this.productsRepository 查询数据，别名依然是必须的，以满足 TypeORM 的 API 要求
  async findAll(query: any): Promise<any> {
    const { page = 1, limit = 10 } = query;
    const skip = (page - 1) * limit;
    const whereParams = this.buildWhereParams(query);
    const selectFields = [
      'product.id',
      'product.name',
      'product.pic',
      'product.addr',
      'product.category',
      'product.status',
      // 'category.name',
    ]; // 需要的字段
    try {
      const [data, total] = await this.productsRepository
        .createQueryBuilder('product')
        // .leftJoinAndSelect('product.category', 'category') // 连接`product-category`表，并给它取别名为`category` (需要建立关联关系)
        .select(selectFields)
        .where(whereParams)
        .skip(skip)
        .take(limit)
        .orderBy({ updatedAt: 'DESC' })
        .getManyAndCount();
      return { total, data };
    } catch (error) {
      throw new Error(`Failed to get products: ${error.message}`);
    }
  }
  buildWhereParams(query: any) {
    const { keyword, category, recommend, excludeIds, status } = query;
    let whereParams = {};
    if (status) {
      whereParams = Object.assign(whereParams, {
        status,
      });
    }
    if (keyword) {
      whereParams = Object.assign(whereParams, {
        name: Like(`%${keyword}%`),
      });
    }

    if (category) {
      whereParams = Object.assign(whereParams, { category });
    }

    if (recommend) {
      whereParams = Object.assign(whereParams, {
        recommend: recommend === 'true' ? true : '',
      });
    }
    // 排除一组特定的ids
    if (excludeIds) {
      const ids = excludeIds.split(','); // 将id字符串转换为数字数组
      whereParams = Object.assign(whereParams, {
        id: Not(In(ids)), // 使用Not和In函数进行排除
      });
    }
    return whereParams;
  }
  // 根据ID查找
  async findOneById(id: string): Promise<any> {
    return this.productsRepository
      .createQueryBuilder()
      .where([{ route: id }, { id }])
      .getOne();
  }

  // 数量
  async getCount() {
    return await this.productsRepository.count();
  }
}
